package com.yanqu.manager;

import com.yanqu.dao.CustomGoodsBaseValueDataDaoImpl;
import com.yanqu.dao.CustomThresholdRatioDataDaoImpl;
import com.yanqu.dao.GoodsIgnoreDataDaoImpl;
import com.yanqu.data.entity.setting.CustomGoodsBaseValueData;
import com.yanqu.data.entity.setting.CustomThresholdRatioData;
import com.yanqu.data.entity.setting.GoodsIgnoreData;
import com.yanqu.road.server.TempMgr;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 道具监控阈值管理
 */
public class UserGoodsMonitorSettingMgr extends TempMgr {

    //道具白名单 channelId goodsId
    private static Map<Integer, Map<Integer, GoodsIgnoreData>> whiteGoodsMap = new ConcurrentHashMap<>();

    //道具阈值定制 channelId vip goodsId
    private static Map<Integer, Map<Integer, Map<Integer, CustomGoodsBaseValueData>>> customBaseValueMap = new ConcurrentHashMap<>();

    //用户群阈值倍率 channelId vip goodsId
    private static Map<Integer, Map<Integer, Map<Integer, List<CustomThresholdRatioData>>>> thresholdMap = new ConcurrentHashMap<>();

    /**
     * 白名单数据最大的id
     */
    private static AtomicLong whiteMaxId = new AtomicLong(0);

    /**
     * 道具阈值定制数据最大的id
     */
    private static AtomicLong customMaxId = new AtomicLong(0);

    private static AtomicLong rationMaxId = new AtomicLong(0);


    //最后更新时间
    private static long lastUpdateTime = 0;


    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    public static Map<Integer, Map<Integer, GoodsIgnoreData>> getWhiteGoodsMap() {
        return whiteGoodsMap;
    }

    public static void setWhiteGoodsMap(Map<Integer, Map<Integer, GoodsIgnoreData>> whiteGoodsMap) {
        UserGoodsMonitorSettingMgr.whiteGoodsMap = whiteGoodsMap;
    }

    public static Map<Integer, Map<Integer, Map<Integer, CustomGoodsBaseValueData>>> getCustomBaseValueMap() {
        return customBaseValueMap;
    }

    public static void setCustomBaseValueMap(Map<Integer, Map<Integer, Map<Integer, CustomGoodsBaseValueData>>> customBaseValueMap) {
        UserGoodsMonitorSettingMgr.customBaseValueMap = customBaseValueMap;
    }

    public static AtomicLong getWhiteMaxId() {
        return whiteMaxId;
    }

    public static void setWhiteMaxId(AtomicLong whiteMaxId) {
        UserGoodsMonitorSettingMgr.whiteMaxId = whiteMaxId;
    }

    public static AtomicLong getCustomMaxId() {
        return customMaxId;
    }

    public static void setCustomMaxId(AtomicLong customMaxId) {
        UserGoodsMonitorSettingMgr.customMaxId = customMaxId;
    }

    public static long getLastUpdateTime() {
        return lastUpdateTime;
    }

    public static void setLastUpdateTime(long lastUpdateTime) {
        UserGoodsMonitorSettingMgr.lastUpdateTime = lastUpdateTime;
    }

    @Override
    public boolean reloadData() throws Exception {

        whiteMaxId = new AtomicLong(new GoodsIgnoreDataDaoImpl().getMaxId());
        whiteGoodsMap = new GoodsIgnoreDataDaoImpl().getGoodsIgnoreData();

        customMaxId = new AtomicLong(new CustomGoodsBaseValueDataDaoImpl().getMaxId());
        customBaseValueMap = new CustomGoodsBaseValueDataDaoImpl().getCustomGoodsBaseValueData();

        rationMaxId = new AtomicLong(new CustomThresholdRatioDataDaoImpl().getMaxId());
        thresholdMap = new CustomThresholdRatioDataDaoImpl().getCustomThresholdRatioData();
        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }

    public static GoodsIgnoreData getGoodsIgnoreData(int channelId, int goodsId){
        Map<Integer, GoodsIgnoreData> map = whiteGoodsMap.get(channelId);
        if(map == null){
            return null;
        }
        return map.get(goodsId);
    }

    public static boolean isGoodsIgnore(int channelId, int goodsId){
        GoodsIgnoreData goodsIgnoreData = getGoodsIgnoreData(channelId, goodsId);
        return goodsIgnoreData != null && goodsIgnoreData.getDeleted() == 0;
    }


    public static void addGoodsIgnoreData(GoodsIgnoreData data) {
        Map<Integer, GoodsIgnoreData> map = whiteGoodsMap.get(data.getChannelId());
        if(map == null){
            synchronized (whiteGoodsMap){
                map = whiteGoodsMap.get(data.getChannelId());
                if(map == null){
                    map = new ConcurrentHashMap<>();
                    whiteGoodsMap.put(data.getChannelId(), map);
                }
            }
        }
        synchronized (map){
            if(!map.containsKey(data.getGoodsId())){
                data.setDbId(whiteMaxId.incrementAndGet());
                map.put(data.getGoodsId(), data);
            }
        }
    }

    public static void addCustomGoodsBaseValueData(CustomGoodsBaseValueData data){
        Map<Integer, Map<Integer, CustomGoodsBaseValueData>> vipMap = customBaseValueMap.get(data.getChannelId());
        if(vipMap == null){
            synchronized (customBaseValueMap){
                vipMap = customBaseValueMap.get(data.getChannelId());
                if(vipMap == null){
                    vipMap = new ConcurrentHashMap<>();
                    customBaseValueMap.put(data.getChannelId(), vipMap);
                }
            }
        }
        Map<Integer, CustomGoodsBaseValueData> goodsMap = vipMap.get(data.getVip());
        if(goodsMap == null){
            synchronized (vipMap){
                goodsMap = vipMap.get(data.getVip());
                if(goodsMap == null){
                    goodsMap = new ConcurrentHashMap<>();
                    vipMap.put(data.getVip(), goodsMap);
                }
            }
        }
        synchronized (goodsMap){
            if(!goodsMap.containsKey(data.getGoodsId())){
                data.setDbId(customMaxId.incrementAndGet());
                goodsMap.put(data.getGoodsId(), data);
            }
        }
    }

    public static CustomGoodsBaseValueData getCustomGoodsBaseValueData(int channelId, int vip, int goods){
        Map<Integer, Map<Integer, CustomGoodsBaseValueData>> map = customBaseValueMap.get(channelId);
        if(map == null){
            return null;
        }
        Map<Integer, CustomGoodsBaseValueData> dataMap = map.get(vip);
        if(dataMap == null){
            return null;
        }
        return dataMap.get(goods);
    }

    public static void addCustomThresholdRatioData(CustomThresholdRatioData data){
        Map<Integer, Map<Integer, List<CustomThresholdRatioData>>> vipMap = thresholdMap.get(data.getChannelId());
        if(vipMap == null){
            synchronized (thresholdMap){
                vipMap = thresholdMap.get(data.getChannelId());
                if(vipMap == null){
                    vipMap = new ConcurrentHashMap<>();
                    thresholdMap.put(data.getChannelId(), vipMap);
                }
            }
        }
        Map<Integer, List<CustomThresholdRatioData>> goodsMap = vipMap.get(data.getVip());
        if(goodsMap == null){
            synchronized (vipMap){
                goodsMap = vipMap.get(data.getVip());
                if(goodsMap == null){
                    goodsMap = new ConcurrentHashMap<>();
                    vipMap.put(data.getVip(), goodsMap);
                }
            }
        }
        List<CustomThresholdRatioData> dataList = goodsMap.get(data.getThresholdType());
        if(dataList == null){
            synchronized (goodsMap){
                dataList = goodsMap.get(data.getThresholdType());
                if(dataList == null){
                    dataList = new ArrayList<>();
                    goodsMap.put(data.getThresholdType(), dataList);
                }
            }
        }
        synchronized (dataList){
            data.setDbId(rationMaxId.incrementAndGet());
            dataList.add(data);
        }
    }

    public static List<CustomThresholdRatioData> getCustomThresholdRatioData(int channelId, int vip, int type){
        Map<Integer, Map<Integer, List<CustomThresholdRatioData>>> map = thresholdMap.get(channelId);
        if(map == null){
            return null;
        }
        Map<Integer, List<CustomThresholdRatioData>> dataMap = map.get(vip);
        if(dataMap == null){
            return null;
        }
        return dataMap.get(type);
    }


    @Override
    public boolean save() {
        for (Map.Entry<Integer, Map<Integer, GoodsIgnoreData>> entry : whiteGoodsMap.entrySet()) {
            for (Map.Entry<Integer, GoodsIgnoreData> dataEntry : entry.getValue().entrySet()) {
                GoodsIgnoreData data = dataEntry.getValue();
                if(data.isInsertOption()){
                    new GoodsIgnoreDataDaoImpl().add(data);
                }else if(data.isUpdateOption()){
                    new GoodsIgnoreDataDaoImpl().update(data);
                }
            }
        }

        for (Map.Entry<Integer, Map<Integer, Map<Integer, CustomGoodsBaseValueData>>> entry : customBaseValueMap.entrySet()) {
            for (Map.Entry<Integer, Map<Integer, CustomGoodsBaseValueData>> mapEntry : entry.getValue().entrySet()) {
                for (Map.Entry<Integer, CustomGoodsBaseValueData> dataEntry : mapEntry.getValue().entrySet()) {
                    CustomGoodsBaseValueData data = dataEntry.getValue();
                    if(data.isInsertOption()){
                        new CustomGoodsBaseValueDataDaoImpl().add(data);
                    }else if(data.isUpdateOption()){
                        new CustomGoodsBaseValueDataDaoImpl().update(data);
                    }
                }
            }
        }
        for (Map.Entry<Integer, Map<Integer, Map<Integer, List<CustomThresholdRatioData>>>> entry : thresholdMap.entrySet()) {
            for (Map.Entry<Integer, Map<Integer, List<CustomThresholdRatioData>>> mapEntry : entry.getValue().entrySet()) {
                for (Map.Entry<Integer, List<CustomThresholdRatioData>> dataEntry : mapEntry.getValue().entrySet()) {
                    List<CustomThresholdRatioData> value = dataEntry.getValue();
                    for (int i = 0; i < value.size(); i++) {
                        CustomThresholdRatioData data = value.get(i);
                        if(data.isInsertOption()){
                            new CustomThresholdRatioDataDaoImpl().add(data);
                        }else if(data.isUpdateOption()){
                            new CustomThresholdRatioDataDaoImpl().update(data);
                        }
                    }
                }
            }
        }
        return true;
    }
}
